/*
* $Id: HousingManager.java 265 2011-02-07 23:13:07Z volok-aleksej@yandex.ru $
*
* Copyright 2008-2011 by Volokitin Alexey
* All rights reserved
*
*/
package apiary.db.managers;

import java.io.IOException;
import java.util.Vector;

import java.util.Enumeration;
import java.util.Hashtable;

import apiary.Apiary;
import apiary.ui.journal.HousingForm.HousingValue;
import apiary.db.HousingStore;
import apiary.db.HousingStore.HousingRecord;
import apiary.db.TypeStore;
import apiary.db.TypeStore.TypeRecord;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;

/**
 * Hive database manager
 * @author lexus
 */
public class HousingManager
{
    /** instance class */
    private static HousingManager instance = null;
    /**
     * Gets instance class
     * @return instance class
     */
    public static HousingManager GetInstance() {
        return instance;
    }

    /** hive database */
    private HousingStore housingStore;
    /** type of hive database */
    private TypeStore typeHStore;
    /** type of frame database */
    private TypeStore typeFStore;
    /** maximal hive identificator */
    private int maxIdHousing;
    /** list of hive */
    private Vector dbHousing;
    /** list of hive types */
    private Hashtable dbTypeH;
    /** list of frame types */
    private Hashtable dbTypeF;

    /**
     * Constructor
     */
    public HousingManager() {
        instance = this;
        typeHStore = new TypeStore(TypeStore.TYPE_HOUSING_STORE);
        typeFStore = new TypeStore(TypeStore.TYPE_FRAME_STORE);
        housingStore = new HousingStore();
        dbHousing = new Vector();
        dbTypeH = new Hashtable();
        dbTypeF = new Hashtable();
        hashTypes();
        readHousing();
    }

    /**
     * Adds hive at list.
     * Converts hive to database format and adds at list.
     * @param housing hive value
     * @return binary data that describe hive
     */
    protected byte[] addHousing(HousingValue housing) {
        maxIdHousing = nextIdHousing();
        HousingRecord housingRecord = (HousingRecord) housingStore.getRecord();
        housingRecord.idHousing = maxIdHousing;
        ConvertData.HousingValueToRecord(housing, housingRecord);
        dbHousing.addElement(housingRecord);
        return housingRecord.getData();
    }

    /**
     * Adds hive at list.
     * Data will be parsed and created new hive object.
     * @param data binary data that describe hive
     */
    protected void addHousing(byte[] data) {
        HousingRecord housingRecord = (HousingRecord) housingStore.getRecord();
        housingRecord.setData(data);
        dbHousing.addElement(housingRecord);
        if(maxIdHousing < housingRecord.idHousing)
            maxIdHousing = housingRecord.idHousing;
    }

    /**
     * Changes hive at list.
     * Converts hive to database format and changes at list.
     * @param id identificator hive
     * @param housing hive value
     * @return binary data that describe hive
     */
    protected byte[] changeHousing(int id, HousingValue housing) {
        HousingRecord housingRecord = getHousing(id);
        if(housingRecord == null)
            return null;
        ConvertData.HousingValueToRecord(housing, housingRecord);
        return housingRecord.getData();
    }
    
    /**
     * Changes hive at list.
     * Data will be parsed and changed hive object.
     * @param data binary data that describe hive
     */
    protected void changeHousing(byte[] data) {
        HousingRecord housingRecord = (HousingRecord) housingStore.getRecord();
        housingRecord.setData(data);
        HousingRecord housing = getHousing(housingRecord.idHousing);
        if(housing == null)
            return;
        housing.setData(data);
    }

    /**
     * Delete hive from list.
     * @param id identificator of hive
     */
    protected byte[] deleteHousing(int id) {
        try {
            deleteHousingFromList(id);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream dos = new DataOutputStream(baos);
            dos.writeInt(id);
            return baos.toByteArray();
        } catch (IOException ex) {}
        return null;
    }

    /**
     * Delete hive from list.
     * @param value binary data that describe hive
     */
    protected void deleteHousing(byte[] value) {
        try {
            ByteArrayInputStream bais = new ByteArrayInputStream(value);
            DataInputStream dis = new DataInputStream(bais);
            deleteHousingFromList(dis.readInt());
        } catch (IOException ex) {}
    }

    /**
     * Reads hive and types databases
     */
    private void readHousing() {
        Enumeration housingsEnum = housingStore.getRecordsEnumeration();
        do {
            if(!housingsEnum.hasMoreElements())
                break;
            HousingRecord record = (HousingRecord) housingsEnum.nextElement();
            dbHousing.addElement(record);
            if(maxIdHousing < record.idHousing)
                maxIdHousing = record.idHousing;
        } while(true);
        Enumeration typeHEnum = typeHStore.getRecordsEnumeration();
        do {
            if(!typeHEnum.hasMoreElements())
                break;
            TypeRecord record = (TypeRecord) typeHEnum.nextElement();
            Integer idType = new Integer(record.idType);
            if(record.idType > 7)
                dbTypeH.put(idType, record.nameType);
        } while(true);
        Enumeration typeFEnum = typeFStore.getRecordsEnumeration();
        do {
            if(!typeFEnum.hasMoreElements())
                break;
            TypeRecord record = (TypeRecord) typeFEnum.nextElement();
            Integer idType = new Integer(record.idType);
            if(record.idType > 6)
                dbTypeF.put(idType, record.nameType);
        } while(true);
    }

    /**
     * Delete hive from list.
     * @param id identificator of hive
     */
    protected void deleteHousingFromList(int id) {
        for(int i = 0; i < dbHousing.size(); i++) {
            HousingRecord housing = (HousingRecord) dbHousing.elementAt(i);
            if(housing.idHousing == id) {
                dbHousing.removeElementAt(i);
                break;
            }
        }
    }

    /**
     * Gets hives that is occupated family
     * @param idFamily identificator of family
     * @return list of hive
     */
    protected Vector getHousings(int idFamily) {
        Vector housings = new Vector();
        for(int i = 0; i < dbHousing.size(); i++) {
            HousingRecord housing = (HousingRecord) dbHousing.elementAt(i);
            if(housing.idFamily == idFamily)
                housings.addElement(housing);
        }
        return housings;
    }

    /**
     * Gets hive on identificator
     * @param id identificator of hive
     * @return hive
     */
    protected HousingRecord getHousing(int id) {
        for(int i = 0; i < dbHousing.size(); i++) {
            HousingRecord housing = (HousingRecord) dbHousing.elementAt(i);
            if(housing.idHousing == id)
                return housing;
        }
        return null;
    }

    /**
     * Gets types of hive
     * @return list of types
     */
    protected Hashtable getTypesHousing() {
        return dbTypeH;
    }

    /**
     * Gets types of frame
     * @return list of types
     */
    protected Hashtable getTypesFrame() {
        return dbTypeF;
    }

    /**
     * Fills types
     */
    private void hashTypes() {
        Apiary apiary = Apiary.getInstance();
        dbTypeH.put(new Integer(TypeStore.TYPEH_8),
                  apiary.getLocaleString("TypeH8"));
        dbTypeH.put(new Integer(TypeStore.TYPEH_10),
                  apiary.getLocaleString("TypeH10"));
        dbTypeH.put(new Integer(TypeStore.TYPEH_12),
                  apiary.getLocaleString("TypeH12"));
        dbTypeH.put(new Integer(TypeStore.TYPEH_16),
                  apiary.getLocaleString("TypeH16"));
        dbTypeH.put(new Integer(TypeStore.TYPEH_18),
                  apiary.getLocaleString("TypeH18"));
        dbTypeH.put(new Integer(TypeStore.TYPEH_20),
                  apiary.getLocaleString("TypeH20"));
        dbTypeH.put(new Integer(TypeStore.TYPEH_24),
                  apiary.getLocaleString("TypeH24"));
        dbTypeH.put(new Integer(TypeStore.TYPEH_NONSDT),
                  apiary.getLocaleString("TypeNonStandart"));

        dbTypeF.put(new Integer(TypeStore.TYPEF_300),
                  apiary.getLocaleString("TypeF300"));
        dbTypeF.put(new Integer(TypeStore.TYPEF_230),
                  apiary.getLocaleString("TypeF230"));
        dbTypeF.put(new Integer(TypeStore.TYPEF_180),
                  apiary.getLocaleString("TypeF180"));
        dbTypeF.put(new Integer(TypeStore.TYPEF_SECTION),
                  apiary.getLocaleString("TypeFSection"));
        dbTypeF.put(new Integer(TypeStore.TYPEF_W230),
                  apiary.getLocaleString("TypeFW230"));
        dbTypeF.put(new Integer(TypeStore.TYPEF_W180),
                  apiary.getLocaleString("TypeFW180"));
        dbTypeF.put(new Integer(TypeStore.TYPEF_NONSDT),
                  apiary.getLocaleString("TypeNonStandart"));
    }

    /**
     * Calculates next hive identificator
     * @return identificator
     */
    private int nextIdHousing() {
        return maxIdHousing + 1;
    }
}
